const Cc = Components.classes;
const Ci = Components.interfaces;
const NativeJSON = Cc["@mozilla.org/dom/json;1"]
                     .createInstance(Ci.nsIJSON);
const IOService  = Cc["@mozilla.org/network/io-service;1"].
                     getService(Ci.nsIIOService);
const DNSService = Cc["@mozilla.org/network/dns-service;1"].
                     getService(Ci.nsIDNSService);
const URLParser = Cc["@mozilla.org/network/url-parser;1?auth=no"]
                    .getService(Ci.nsIURLParser);
const SocketTransportService = Cc["@mozilla.org/network/socket-transport-service;1"].
                                 getService(Ci.nsISocketTransportService);
const ThreadManager = Cc["@mozilla.org/thread-manager;1"].
                        getService();
const PrefService = Cc["@mozilla.org/preferences-service;1"].
                      getService(Ci.nsIPrefService);
const DirectoryService = Cc["@mozilla.org/file/directory_service;1"].
                           getService(Ci.nsIProperties);
const StorageService = Cc["@mozilla.org/storage/service;1"].
                         getService(Ci.mozIStorageService);
const StorageStatementWrapper = Components.Constructor("@mozilla.org/storage/statement-wrapper;1",
                                                       "mozIStorageStatementWrapper",
                                                       "initialize");

const gMainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIWebNavigation)
                      .QueryInterface(Ci.nsIDocShellTreeItem)
                      .rootTreeItem
                      .QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIDOMWindow);

function extend(target, source, overwrite) {
  overwrite = overwrite == null ? true : overwrite;
  for (var p in source) {
    var getter = source.__lookupGetter__(p);
    if(getter) target.__defineGetter__(p, getter);
    var setter = source.__lookupSetter__(p);
    if(setter) target.__defineSetter__(p, setter);
    if(!getter && !setter && (overwrite || !(p in target)))
      target[p] = source[p];
  }
  return target;
}

function update(self, obj) {
  if (self === null) {
    self = {};
  }
  for (var i = 1; i < arguments.length; i++) {
    var o = arguments[i];
    if (typeof(o) != "undefined" && o !== null) {
      for (var k in o) {
        self[k] = o[k];
      }
    }
  }
  return self;
}

function p(x) {
  if (typeof x == "object") x = objectToJSON(x);
  Application.console.log(x ? x : "““");
}

function objectToJSON(aObject) {
  switch (typeof aObject) {
  case "undefined":
  case "function":
  case "unknown": return null;
  case "boolean": return aObject.toString();
  }
  if (aObject === null) return "null";
  if (aObject.toJSON) return aObject.toJSON();
  var results = [];
  for (var p in aObject) {
    results.push(p + ": " + aObject[p]);
  }
  return "{" + results.join(", ") + "}";
}

function $A(aObj) {
  if (!aObj) return false;
  switch (typeof aObj) {
  case "string":
    return aObj.split("");
  case "object":
    if (aObj instanceof Array) return [].concat(aObj);
    let length = aObj.length || 0, results = new Array(length);
    while (length--) results[length] = aObj[length];
    return results;
  default:
    return false;
  }
}

function filterMap(aArray, aProc) {
  var a = [];
  for (var i = 0; i < aArray.length; i++) {
    var r = aProc(aArray[i]);
    if (r !== false) a.push(r);
  }
  return a;
}

function deleteDupulicated(aArray, aCompareFunc) {
  aCompareFunc = aCompareFunc ? aCompareFunc : function comp(x, y) {return x == y;};
  var res = [];
  aArray.forEach(function(x) {
                   if (!res.some(function(y) {return aCompareFunc(x, y);}))
                     res.push(x);
                   });
  return res;
}

function decapitalize(aString) {
  return aString.substr(0, 1).toLowerCase() + aString.substr(1);
}

function stringPrefixP(aString, aStringPrefix) {
  return (aStringPrefix == aString.toString().substr(0, aStringPrefix.length));
}

function test() {
  Components.utils.import("resource://musubi/modules/test.jsm");
  alert(foo());
  return;
  var WindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
                          .getService(Ci.nsIWindowMediator);
  var enum = WindowMediator.getEnumerator(null);
  while(enum.hasMoreElements()){
    var win = enum.getNext();
  }
}

function openDebugConsole() {
  var debugConsole = document.getElementById("debug-console");
  debugConsole.collapsed = !debugConsole.collapsed;
}
